fix(client): location buffer — off-thread, flicker-free, reliable slider commit#351
Open
mbarrenechea wants to merge 7 commits into
Open
fix(client): location buffer — off-thread, flicker-free, reliable slider commit#351mbarrenechea wants to merge 7 commits into
mbarrenechea wants to merge 7 commits into
Conversation
Uploading a long polyline (e.g. the ~887 km BR-319) froze the app for seconds. The cost wasn't the input vertex count — it tracked road length, which fingerprinted ArcGIS geodesicBuffer densifying the offset curve into thousands of vertices. That ran synchronously on the main thread from every path that touches a location: the upload dialog, the ~29 useLocationGeometry consumers, and the area_afp bounds check (geometryEngine.intersects). Move all of it to geometryEngineAsync (runs in a worker): geodesicBuffer, intersects, and geodesicArea. getGeometryWithBuffer/useLocationGeometry become async, and the shared buffer cache now keys on the in-flight promise so concurrent consumers share one computation. Sketch's drawBuffer is async and debounces the reshape redraw. Refs: AM
Dragging the buffer slider wrote location.buffer on every pointer-move, re-firing the async buffer for each intermediate value, so a flurry of delayed recomputations landed after the drag ended. Drive the slider/label from local state while dragging and commit to location on onValueCommit, so the buffer is recomputed once per drag. Refs: AM
Moving geodesicBuffer off-thread left the sketch buffer layer cleared synchronously but redrawn after the worker resolved, so the buffer blinked out on every location change (e.g. committing a buffer-slider value). A rejected/superseded async buffer could also leave the layer empty. Let drawBuffer own the buffer layer: clear the old graphic only once the new one is ready, guard the redraw with a monotonic token so a stale resolve can't clobber a newer one, and catch worker errors so a failed buffer keeps the current one instead of clearing it. Refs: AM
The async geodesicBuffer worker can reject or resolve empty transiently (cold load, rapid slider commits). drawBuffer then kept the stale ring, so the buffer on the map sometimes didn't resize after releasing the slider. Recompute synchronously on worker failure/empty so the ring always reflects the latest buffer; the async fast path still handles the common case, so the long-polyline freeze stays avoided. Refs: AM
…draw ring" This reverts commit 0b07caa.
The buffer slider is controlled by React state updated in onValueChange. Radix only fires onValueCommit when its (controlled) value differs from the slide-start value; on a fast drag the state hasn't flushed by pointer-up, so Radix sees no change and skips onValueCommit entirely. location.buffer never updates and the ring/area keep the old size, while the label (also the local state) flushes a beat later and looks correct. A track click commits via a different path, so it was always reliable. Capture each change in a ref and commit the final value on a trailing debounce off onValueChange, independent of whether Radix fires onValueCommit. Still one commit per drag. Refs: AM
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
Long polylines take ~700ms to buffer off-thread; the area and buffer value silently lagged the slider. Expose an isCalculating flag from a new useLocationGeometryWithStatus hook and render an inline spinner next to the area km2 and buffer value in the create + confirm panels.
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.


Summary
Fixes the location buffer behaving badly when adjusting the buffer slider — disappearing, flickering, freezing the UI on long polylines, and (most reported) not resizing on fast drags.
ba0ab36f): buffering a long polyline (e.g. the ~887 km / 2,833-vtx BR-319) rangeodesicBuffersynchronously and froze the app for ~700ms on every location touch. Moved buffering/intersects/area togeometryEngineAsync(worker); shared the in-flight promise across the ~29useLocationGeometryconsumers via a cache keyed on geometry+buffer+SR.2629974d): the slider wrotelocation.bufferon every pointer-move, re-firing the async buffer per tick. Drive the slider/label from local state and commit once per drag.0d5ce54c): moving buffering off-thread put anawaitbetween Sketch's eagerbufferRef.removeAll()and the redraw, so the ring blinked out mid-recompute.drawBuffernow owns the buffer layer — clears the old graphic only once the new one is ready — plus a monotonic token so a stale async result can't clobber a newer one.50821b97): the slider's controlled value is React state set inonValueChange; on a fast drag it hasn't flushed by pointer-up, so Radix sees no change vs slide-start and skipsonValueCommitentirely →location.buffernever updates and the ring keeps the old size (label looked right because it flushes a beat later). A track click commits via a different path, so it was always reliable. Now each change is captured in a ref and committed on a trailing debounce, independent of whether Radix firesonValueCommit.0b07caa6→79f95708): its premise (worker rejection) never occurred in testing.Test plan